﻿/*
 * Copyright (c) 2010 Piotr Polesiuk
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Fotometr
{
    public partial class FotometrMainWindow : Form
    {
        #region Private variables

        private ToolStripButton _checkedToolButton;

        private int _lastMousePosX;
        private int _lastMousePosY;

        private Settings _settingsWindow;

        #endregion

        public FotometrMainWindow()
        {
            InitializeComponent();

            _settingsWindow = new Settings();
        }

        private void otwórzToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.Filter = "Plik graficzny (*.bmp; *.jpg; *.jpeg; *.png)|*.bmp;*.jpg;*.jpeg;*.png|"
                                    +"Mapa bitowa (*.bmp)|*.bmp|"
                                    +"Plik JPEG (*.jpg; *.jpeg)|*.jpg;*.jpeg|"
                                    +"Plik PNG (*.png)|*.png|"
                                    +"Wszystkie pliki (*.*)|*.*";
            openFileDialog.CheckFileExists = true;
            openFileDialog.Title = "Otwórz obraz";
            DialogResult fDialResult = openFileDialog.ShowDialog();

            if (fDialResult == DialogResult.OK)
            {
                try
                {
                    Core.Bitmap = new Bitmap(openFileDialog.FileName);
                    imagePanel.Size = new Size((int)(Core.Bitmap.Width * Core.Scale), 
                        (int)(Core.Bitmap.Height * Core.Scale));
                    imagePanel.Invalidate();
                }
                catch (ArgumentException)
                {
                    MessageBox.Show("\"" + openFileDialog.FileName + "\" nie jest poprawnym, rozpoznawalnym plikiem graficznym.",
                        "Niepoprawny plik", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void powiększToolStripMenuItem_Click(object sender, EventArgs e)
        {
            splitContainer1.Panel1.HorizontalScroll.Value =
                splitContainer1.Panel1.HorizontalScroll.Value * 3 / 2;
            splitContainer1.Panel1.VerticalScroll.Value =
                splitContainer1.Panel1.VerticalScroll.Value * 3 / 2;
            Core.Scale *= 1.5f;
            if (Core.Scale > 16.0f)
                Core.Scale = 16.0f;
            if (Core.Bitmap != null)
            {
                imagePanel.Size = new Size((int)(Core.Bitmap.Width * Core.Scale), 
                    (int)(Core.Bitmap.Height * Core.Scale));
                imagePanel.Invalidate();
            }
        }

        private void zmniejszToolStripMenuItem_Click(object sender, EventArgs e)
        {
            splitContainer1.Panel1.HorizontalScroll.Value =
                splitContainer1.Panel1.HorizontalScroll.Value * 2 / 3;
            splitContainer1.Panel1.VerticalScroll.Value =
                splitContainer1.Panel1.VerticalScroll.Value * 2 / 3;
            Core.Scale /= 1.5f;
            if (Core.Scale < 1.0f/16.0f)
                Core.Scale = 1.0f / 16.0f;
            if (Core.Bitmap != null)
            {
                imagePanel.Size = new Size((int)(Core.Bitmap.Width * Core.Scale),
                    (int)(Core.Bitmap.Height * Core.Scale));
                imagePanel.Invalidate();
            }
        }

        private void zoomTool_Click(object sender, EventArgs e)
        {
            if (_checkedToolButton == zoomToolButton)
            {
                _checkedToolButton = null;
                Core.SelectedTool = Core.Tool.Null;
                imagePanel.Cursor = DefaultCursor;
            }
            else
            {
                Core.SelectedTool = Core.Tool.Zoom;
                if (_checkedToolButton != null)
                    _checkedToolButton.Checked = false;
                _checkedToolButton = zoomToolButton;
                imagePanel.Cursor = new Cursor(GetType(), "ZoomCursor.cur");
            }
            int rad = Core.Foto3Radius3 > Core.Foto1Radius ?
                (int)(Core.Foto3Radius3 * Core.Scale) + 1 :
                (int)(Core.Foto1Radius * Core.Scale) + 1;
            imagePanel.Invalidate(new Rectangle(_lastMousePosX - rad, _lastMousePosY - rad, 2 * rad, 2 * rad));
        }

        private void imagePanel_MouseClick(object sender, MouseEventArgs e)
        {
            switch (Core.SelectedTool)
            {
                case Core.Tool.Zoom:
                    if (e.Button == MouseButtons.Left)
                        powiększToolStripMenuItem_Click(sender, e);
                    else if (e.Button == MouseButtons.Right)
                        zmniejszToolStripMenuItem_Click(sender, e);
                    break;
                case Core.Tool.Foto1:
                    if (Core.Bitmap != null)
                    {
                        Core.Foto1Result result = Core.Fotometry1();
                        OutputTextBox.AppendText(Core.FormatValue("R", result.R)
                            + Core.FormatValue("G", result.G)
                            + Core.FormatValue("B", result.B)
                            + Core.FormatValue("R+G+B", result.Total) + "\n");
                        OutputTextBox.ScrollToCaret();

                        Core.ResultList.Add(result);
                    }
                    break;
                case Core.Tool.Foto3:
                    if (Core.Bitmap != null)
                    {
                        Core.Foto3Result result = Core.Fotometry3();
                        OutputTextBox.AppendText(Core.FormatValue("R", result.Data.R)
                            + Core.FormatValue("G", result.Data.G)
                            + Core.FormatValue("B", result.Data.B)
                            + Core.FormatValue("R+G+B", result.Data.Total) + "\n");
                        OutputTextBox.ScrollToCaret();

                        Core.ResultList.Add(result.Data);
                    }
                    break;
                default:
                    break;
            }
        }

        private void foto1ToolButton_Click(object sender, EventArgs e)
        {
            if (_checkedToolButton == foto1ToolButton)
            {
                _checkedToolButton = null;
                Core.SelectedTool = Core.Tool.Null;
                imagePanel.Cursor = DefaultCursor;
            }
            else
            {
                Core.SelectedTool = Core.Tool.Foto1;
                if (_checkedToolButton != null)
                    _checkedToolButton.Checked = false;
                _checkedToolButton = foto1ToolButton;
                imagePanel.Cursor = Cursors.Cross;
            }
            int rad = Core.Foto3Radius3 > Core.Foto1Radius ? 
                (int)(Core.Foto3Radius3 * Core.Scale) + 1 : 
                (int)(Core.Foto1Radius * Core.Scale) + 1;
            imagePanel.Invalidate(new Rectangle(_lastMousePosX - rad, _lastMousePosY - rad, 2 * rad, 2 * rad));
        }

        private void imagePanel_MouseMove(object sender, MouseEventArgs e)
        {
            Core.CursorPositionX = (float)e.X;
            Core.CursorPositionY = (float)e.Y;
            switch (Core.SelectedTool)
            {
                case Core.Tool.Foto1:
                    int rad = (int)(Core.Foto1Radius * Core.Scale) + 1;
                    imagePanel.Invalidate(new Rectangle(_lastMousePosX - rad, _lastMousePosY - rad, 2 * rad, 2 * rad));
                    imagePanel.Invalidate(new Rectangle(e.X - rad, e.Y - rad, 2*rad, 2*rad));
                    break;
                case Core.Tool.Foto3:
                    rad = (int)(Core.Foto3Radius3 * Core.Scale) + 1;
                    imagePanel.Invalidate(new Rectangle(_lastMousePosX - rad, _lastMousePosY - rad, 2 * rad, 2 * rad));
                    imagePanel.Invalidate(new Rectangle(e.X - rad, e.Y - rad, 2 * rad, 2 * rad));
                    break;
                default:
                    break;
            }
            _lastMousePosX = e.X;
            _lastMousePosY = e.Y;
        }

        private void ustawieniaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                _settingsWindow.Show(this);
            }
            catch (ObjectDisposedException)
            {
                _settingsWindow = new Settings();
                _settingsWindow.Show(this);
            }
            catch (InvalidOperationException)
            {
                _settingsWindow.Activate();
            }
        }

        private void foto3ToolStripButton_Click(object sender, EventArgs e)
        {
            if (_checkedToolButton == foto3ToolButton)
            {
                _checkedToolButton = null;
                Core.SelectedTool = Core.Tool.Null;
                imagePanel.Cursor = DefaultCursor;
            }
            else
            {
                Core.SelectedTool = Core.Tool.Foto3;
                if (_checkedToolButton != null)
                    _checkedToolButton.Checked = false;
                _checkedToolButton = foto3ToolButton;
                imagePanel.Cursor = Cursors.Cross;
            }
            int rad = Core.Foto3Radius3 > Core.Foto1Radius ?
                (int)(Core.Foto3Radius3 * Core.Scale) + 1 :
                (int)(Core.Foto1Radius * Core.Scale) + 1;
            imagePanel.Invalidate(new Rectangle(_lastMousePosX - rad, _lastMousePosY - rad, 2 * rad, 2 * rad));
        }

        private void oProgramieToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Fotometr, wersja 1.3. Autor: Piotr Polesiuk.\n" +
                "Copyright (c) 2010 Piotr Polesiuk", "O Fotometrze");
        }

        private void zakończToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void zapiszButton_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            saveFileDialog.Title = "Zapisz dane";
            saveFileDialog.Filter = "Plik tekstowy (*.txt)|*.txt|"
                                    + "Wszystkie pliki (*.*)|*.*";

            DialogResult dialogResult = saveFileDialog.ShowDialog();

            if (dialogResult == DialogResult.OK)
            {
                try
                {
                    System.IO.StreamWriter sw = new System.IO.StreamWriter(saveFileDialog.FileName);
                    sw.WriteLine("R G B R+G+B");
                    foreach (var res in Core.ResultList)
                        sw.WriteLine(res.ToString());
                    sw.Close();
                }
                catch (System.IO.IOException)
                {
                    MessageBox.Show("Nie można zapisać do pliku \"" + saveFileDialog.FileName + "\"", 
                        "Błąd zapisu", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void wyczyscButton_Click(object sender, EventArgs e)
        {
            Core.ResultList.Clear();
            OutputTextBox.Text = "";
        }

        private void licencjaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show(
                "Copyright (c) 2010 Piotr Polesiuk\n\n" +
                "Permission is hereby granted, free of charge, to any person obtaining a copy " +
                "of this software and associated documentation files (the \"Software\"), to deal " +
                "in the Software without restriction, including without limitation the rights " +
                "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell " +
                "copies of the Software, and to permit persons to whom the Software is " +
                "furnished to do so, subject to the following conditions:\n\n" +
                "The above copyright notice and this permission notice shall be included in " +
                "all copies or substantial portions of the Software.\n\n" +
                "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR " +
                "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, " +
                "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE " +
                "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER " +
                "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, " +
                "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN " +
                "THE SOFTWARE.", "Licencja");
        }
    }
}
